package pl.engine.view
{
	import pl.engine.camera.Camera;
	import pl.engine.model.MapGrid;
	import pl.engine.model.vo.BaseMapTile;
	import pl.engine.model.vo.obstacle.IBaseObstacle;
	import pl.engine.ui.UI;
	import pl.textures.TextureID;
	import pl.textures.Textures;

	import starling.display.DisplayObjectContainer;
	import starling.display.Image;
	import starling.display.Sprite;

	import flash.geom.Point;

	/**
	 * ...
	 * @author Bakudo
	 */
	public class View extends Sprite implements IView
	{
		private var bgLayer:Sprite = new Sprite();
		private var uiFlatLayer:Sprite = new Sprite();
		private var obstaclesLayer:Sprite = new Sprite();
		public var layers:Sprite = new Sprite();
		private var center:Image;
		private var bgTiles:Vector.<BaseMapTile> = new Vector.<BaseMapTile>();
		private var obstacles:Vector.<IBaseObstacle> = new Vector.<IBaseObstacle>();
		private var imageToAdd:Image;
		private var obstacleToAdd:Image;
		private static var _instance:View;
		public static var obstaclesNeedSorting:Boolean;

		public function View()
		{
			_instance = this;
			addChild( layers );
			layers.addChild( bgLayer );
			layers.addChild( uiFlatLayer );
			layers.addChild( obstaclesLayer );
			center = new Image( Textures.getSingleTexture( TextureID.CROSS ).texture );
			addChild( center );
			UI.registerUIHandlers( null, mouseMoveHandler );
		}

		private function mouseMoveHandler():void
		{
			var pi:Point = UI.cursor.getIsoPosition();
			var p:Point = Camera.convertIsoToRect( pi.x, pi.y );
			var tp:Point = new Point( Math.floor( p.x / MapGrid.TILE_W ), Math.floor( p.y / MapGrid.TILE_H ) );

			// selectTile( tp.x, tp.y );
		}

		public static function getView():DisplayObjectContainer
		{
			return _instance.layers;
		}

		public function setCenterCrossPosition( px:Number, py:Number ):void
		{
			center.x = px - center.width / 2;
			center.y = py - center.height / 2;
		}

		public function setViewPosition( px:Number, py:Number ):void
		{
			layers.x = Math.floor( px );
			layers.y = Math.floor( py );
		}

		public function cleanUpBgLayer():void
		{
			var i:uint = 0;
			var n:uint = bgTiles.length;
			var tile:BaseMapTile;
			var removedCount:uint;
			var spliced:Boolean;
			// trace('-----------\nCleanBG\n',obstaclesLayer.numChildren)
			while (i < n)
			{
				tile = bgTiles[i];
				spliced = false;
				if (Camera.isInViewRange( tile.hID, tile.vID ) == false)
				{
					tile.isRendered = false;
					bgLayer.removeChild( tile.tileImage );
					tile.cleanView();
					spliced = true;
					bgTiles.splice( i, 1 );
					removedCount++;
					if (n > 0) n--;
				}
				if (spliced == false) i++;
			}
		}

		public function cleanUpObstaclesLayer():void
		{
			var i:uint = 0;
			var n:uint;

			var sortingFunction:Function = function( ob1:IBaseObstacle, ob2:IBaseObstacle ):int
			{
				if ((ob1.isoY + ob1.pivotY) > (ob2.isoY + ob2.pivotY)) return 1;
				else if ((ob1.isoY + ob1.pivotY) < (ob2.isoY + ob2.pivotY))
				{
					return -1;
				}
				return 0;
			};

			n = obstacles.length;
			var obstacle:IBaseObstacle;
			var removedCount:uint;
			var spliced:Boolean;
			while (i < n)
			{
				obstacle = obstacles[i];
				spliced = false;
				if (Camera.isInViewRange( obstacle.oX, obstacle.oY ) == false)
				{
					obstaclesLayer.removeChild( obstacle.display );
					obstacle.cleanView();
					obstacle.isRendered = false;
					obstacles.splice( i, 1 );
					if (n > 0) n--;
					// spliced = true;
					removedCount++;
				}
				if (spliced == false) i++;
			}
			// if (removedCount > 0) trace( 'Removed count', removedCount, 'Zostalo', obstacles.length, obstaclesLayer.numChildren );
			if (obstaclesNeedSorting == true)
			{
				i = 0;
				n = obstacles.length;

				obstacles = obstacles.sort( sortingFunction );
				obstaclesNeedSorting = false;
				var sorted:uint;
				var omited:uint;
				while (i < n)
				{
					obstacle = obstacles[i];
					if (obstaclesLayer.getChildIndex( obstacle.display ) != i)
					{
						// trace('AddChild at - child id ',obstacle.id,'Ad at : ',i,'container num children ',obstaclesLayer.numChildren,'n',n)
						obstaclesLayer.addChildAt( obstacle.display, i );
						sorted++;
					}
					else
					{
						omited++;
					}
					i++;
				}
				// trace("omited", omited);
			}
		}

		public function setToObstacleLayer( obs:IBaseObstacle ):void
		{
			obstaclesNeedSorting = true;
			obstacles.push( obs );
			obs.isRendered = true;

			obstaclesLayer.addChild( obs.display );
			obs.display.x = obs.isoX;
			obs.display.y = obs.isoY;
			// trace('Dodalem obstacle, ilosci obstacli ',obstaclesLayer.numChildren,obstacles.length);
		}

		public function setToBgLayer( tile:BaseMapTile ):void
		{
			bgTiles.push( tile );
			imageToAdd = new Image( Textures.getSingleTexture( tile.textures[0] ).texture );
			tile.isRendered = true;
			tile.tileImage = imageToAdd;
			imageToAdd.x = imageToAdd.width / 2 * tile.vID + imageToAdd.width / 2 * tile.hID;
			imageToAdd.y = imageToAdd.height / 2 * tile.vID - imageToAdd.height / 2 * tile.hID;
			bgLayer.addChild( imageToAdd );
		}

		public function selectTile( tX:uint, tY:uint ):void
		{
			var isoPos:Point = Camera.convertRectToIso( tX * MapGrid.TILE_W, tY * MapGrid.TILE_H );
			/*while (uiFlatLayer.numChildren > 0)
			uiFlatLayer.removeChildAt( 0 );*/
			var tile:Image;
			if (uiFlatLayer.numChildren == 0)
			{
				tile = new Image( Textures.getTextureAndBitmapById( TextureID.FLAT_SELECTION )[0] );
				uiFlatLayer.addChild( tile );
			}
			else
				tile = uiFlatLayer.getChildAt( 0 ) as Image;

			tile.x = isoPos.x;
			tile.y = isoPos.y - tile.height * .5;
		}
	}
}